#include <QDebug>
#include <QSettings>
#include <QFileInfo>
#include <QPointer>
#include <QTime>
#include "MYPlayer.h"
#include "MYDemuxThread.h"
#include "MYVideoOutput.h"
#include "MYSubTitle.h"

static QScopedPointer<MYDemuxThread> dt;
static QScopedPointer<MYSubtitle> st;

QString intToTime(long long ms) {
	int ss = 1000;
	int mi = ss * 60;
	int hh = mi * 60;
	int dd = hh * 24;

	long day = ms / dd;
	long hour = (ms - day * dd) / hh;
	long minute = (ms - day * dd - hour * hh) / mi;
	long second = (ms - day * dd - hour * hh - minute * mi) / ss;

	int size = 2;

	QString hou = QString::number(hour, 10);
	QString min = QString("%1").arg(minute, size, 10, QChar('0'));
	QString sec = QString("%1").arg(second, size, 10, QChar('0'));

	return hou + ":" + min + ":" + sec;
}

MYPlayer::MYPlayer()
{
    dt.reset(new MYDemuxThread);
    st.reset(new MYSubtitle);
    // 启动demux线程，进行音视频解封解码
    dt->Start();
    // 启动定时器 40ms启动一次，检测是否需要加载字幕，直到KillTimer()被调用
    startTimer(40);
    setBackGround(NULL);
    setVideoPath(NULL);
    setSubTitlePath(NULL);
}

MYPlayer::~MYPlayer()
{
    qDebug() << "close";
    if(m_OpenSuccess)
    {
        // 打开配置文件，保存当前视频的路径和观看到的位置
        QSettings *settingIni = new QSettings("setting.ini",QSettings::IniFormat);
        qDebug()<<m_strTheVideoPath;
        settingIni->setValue("Progress/" + m_strTheVideoPath, dt->pts);
        delete settingIni;
    }
    dt->Close();
}

void MYPlayer::testFunc()
{
    setDemoNum(demoNum() + 1);
}

// 打开线程，传输文件路径
void MYPlayer::urlPass(QString url)
{
	qDebug() << url;
    MYVideoOutput *video = qobject_cast<MYVideoOutput*>(source());
	st.reset(new MYSubtitle);
    qDebug() << (video == nullptr) << endl;
    m_strTheVideoPath = url;
    if(video != nullptr) {
        QFileInfo fileInfo(url);
        QString subTitleP = url.left(url.length() - fileInfo.suffix().length());
        QSettings *settingIni = new QSettings("setting.ini", QSettings::IniFormat);
        QString saveProgress = settingIni->value("Progress/" + url).toString();
        qDebug() << saveProgress;
        delete settingIni;
        // 查找对应字幕文件
        fileInfo = QFileInfo(subTitleP + "srt");
        if(fileInfo.exists()) {
            st->Open(fileInfo.absoluteFilePath());
        }
        else{
            qDebug()<<"there is no srt file " + subTitleP;
        }
        // demux线程加载视频文件
        if(!dt->Open(url.toLocal8Bit(), video)) {
            return;
        }
        // 跳转到上次的观看位置
        if(saveProgress != "") {
            dt->Seek(saveProgress.toDouble() / (double)dt->totalMs);
        }
		QString endtime = intToTime(dt->totalMs);
        setEndTime(endtime);
    }
    qDebug() << url << "pass success";
    setIsPlay(true);
    setOpenSuccess(true);
	dt->SetPause(false);
}

// 播放进度条
void MYPlayer::posFind(double value)
{
    // 位置都精确到千分位
    // 得到当前播放位置
    double pos = (double)(int)((double)dt->pts / (double)dt->totalMs * 1000) / 1000;
    // 计算新的位置
    double newPos = (double)(int)(value * 1000) / 1000;
    qDebug() << "pos value = " << pos;
    dt->Seek(newPos);
}

// 定时器定时事件，用于定时加载字幕
void MYPlayer::timerEvent(QTimerEvent *e)
{
    setTestNum(m_TestNum + 1);
    // 视频，总时长
    long long total = dt->totalMs;
    // 当前位置
    long long currentTime = (int)dt->pts;
	
	QString current = intToTime(currentTime);
	setCurrentTime(current);

    if(st->isOpen()) {
        // 如果已经读取到现在的字幕节点则没必要在read，或者处于刚开始时需要执行read
        if(!(st->nodeStartTime() <= currentTime && st->nodeStartTime() >= currentTime) || (st->nodeStartTime() == st->nodeEndTime())) {
            if(st->Read(currentTime))
                setSubTitleText(st->text());
            else
                setSubTitleText("");
        }
    }
    if(total > 0) {
        double pos = ((double)(int)(((double)dt->pts / (double)total) * 1000)) / 1000;     //保留三位小数，后面置0，方便比较
        setPosNum(pos);
    }
}

// 播放 / 暂停
void MYPlayer::playOrPause()
{
    bool isPause = !dt->isPause;
    setIsPlay(!isPause);
    dt->SetPause(isPause);
}

// 快进
void MYPlayer::goOn()
{
    double pos = ((double)(int)(((double)dt->pts / (double)dt->totalMs) * 1000)) / 1000 + 0.02;   //依照需求调整快进的程度
    dt->Seek(pos);
}

// 快退
void MYPlayer::goBack()
{
    double pos = ((double)(int)(((double)dt->pts / (double)dt->totalMs) * 1000)) / 1000 - 0.02;   //依照需求调整快退的程度
    dt->Seek(pos);
}

// 改变并存储背景
void MYPlayer::changeBackground(QString url)
{
    setBackGround(url);
}

//改变视频选择路径
void MYPlayer::changeVideoPath(QString url)
{
    setVideoPath(url);
}

// 改变字幕文件
void MYPlayer::changeSubtitlePath(QString url)
{
    setSubTitlePath(url);
}

// 改变音量
void MYPlayer::setVolume(double newVolume)
{
    dt->SetVolume(((double)(int)(newVolume*100))/100);
}

// 停止
void MYPlayer::setStop()
{
    if(m_OpenSuccess) {
        dt->Close();
        dt.reset(new MYDemuxThread);
        dt->Start();
        if(st->isOpen()) {
            st.reset(new MYSubtitle);
            setSubTitleText("");
        }
        setOpenSuccess(false);
    }
}

// 加载字幕文件
void MYPlayer::loadSubtitle(QString url)
{
    if(m_OpenSuccess) {
        st.reset(new MYSubtitle);
        st->Open(url);
    }
}

// demoNum
int MYPlayer::demoNum() const
{
    return m_DemoNum;
}

void MYPlayer::setDemoNum(int newValue)
{
    if(m_DemoNum != newValue) {
        m_DemoNum = newValue;
        emit demoNumChanged(m_DemoNum);
    }
}

// testNum
int MYPlayer::testNum() const
{
    return m_TestNum;
}

void MYPlayer::setTestNum(int newValue)
{
    if(m_TestNum != newValue) {
        m_TestNum = newValue;
        emit testNumChanged(m_TestNum);
    }
}

// posNum
double MYPlayer::posNum() const
{
    return m_PosNum;
}

void MYPlayer::setPosNum(double newValue)
{
    if(m_PosNum != newValue) {
        m_PosNum = newValue;
        emit posNumChanged(m_PosNum);
    }
}

// isPlay
bool MYPlayer::isPlay() const
{
    return m_IsPlaying;
}

void MYPlayer::setIsPlay(bool isPlaying)
{
    if(m_IsPlaying != isPlaying) {
        m_IsPlaying = isPlaying;
        emit isPlayingChanged(m_IsPlaying);
    }
}

// openSuccess
bool MYPlayer::openSuccess() const
{
    return m_OpenSuccess;
}

void MYPlayer::setOpenSuccess(bool openSuccess)
{
    if(m_OpenSuccess != openSuccess) {
        m_OpenSuccess = openSuccess;
        emit openSuccessChanged(m_OpenSuccess);
    }
}

// source
QObject* MYPlayer::source() const
{
    return m_Source;

}
void MYPlayer::setSource(QObject *source)
{
    if(m_Source != source) {
        m_Source = source;
        emit sourceChanged(m_Source);
    }
}

// 设置背景图片路径
QString MYPlayer::backGround() const
{
    return m_strBackgroundPath;
}

void MYPlayer::setBackGround(QString url)
{
    QSettings *settingIni = new QSettings("setting.ini", QSettings::IniFormat);
    QString backgroundPath = settingIni->value("Path/Background").toString();
    if(url == NULL) {
        if(backgroundPath == NULL) {
            delete settingIni;
            return;
        }
        else {
            m_strBackgroundPath = backgroundPath;
            QFileInfo fileInfo(backgroundPath);
            m_strBackGroundChoosePath = fileInfo.path();
            qDebug() << m_strBackGroundChoosePath << endl;
            delete settingIni;
            emit backGroundChanged(m_strBackgroundPath);
            emit backGroundChooseChanged(m_strBackGroundChoosePath);
            return;
        }
    }
    // 路径不同则更换
    if(m_strBackgroundPath != url) {
        settingIni->setValue("Path/Background", url);
        QFileInfo fileInfo(backgroundPath);
        m_strBackGroundChoosePath = fileInfo.path();
        emit backGroundChanged(m_strBackgroundPath);
        emit backGroundChooseChanged(m_strBackGroundChoosePath);
    }
    delete settingIni;
}

// 设置选择背景目录
QString MYPlayer::backGroundChoose() const
{
    return m_strBackGroundChoosePath;
}

// 设置选择视频目录
QString MYPlayer::videoPath() const
{
    return m_strVideoPath;
}

void MYPlayer::setVideoPath(QString url)
{
    QSettings *settingIni = new QSettings("setting.ini", QSettings::IniFormat);
    QString videoPath = settingIni->value("Path/VideoChoose").toString();
    if(url == NULL) {
        if(videoPath == NULL) {
            delete settingIni;
            return;
        }
        else {
            m_strVideoPath = videoPath;
            delete settingIni;
            emit videoPathChanged(m_strVideoPath);
            return;
        }
    }
    if(url != m_strVideoPath) {
        QFileInfo fileInfo(url);
        m_strVideoPath = fileInfo.path();
        settingIni->setValue("Path/VideoChoose", m_strVideoPath);
        emit videoPathChanged(m_strVideoPath);
    }
    delete settingIni;
}

// 设置选择字幕路径
QString MYPlayer::subTitlePath() const
{
    return m_strSubTitlePath;
}

void MYPlayer::setSubTitlePath(QString url)
{
    QSettings *settingIni = new QSettings("setting.ini", QSettings::IniFormat);
    QString subtitlePath = settingIni->value("Path/SubTitleChoose").toString();
    if(url == NULL) {
        if(subtitlePath == NULL) {
            delete settingIni;
            return;
        }
        else {
            m_strSubTitlePath = subtitlePath;
            delete settingIni;
            emit subTitlePathChanged(m_strSubTitlePath);
            return;
        }
    }
    if(url != m_strSubTitlePath) {
        QFileInfo fileInfo(url);
        m_strSubTitlePath = fileInfo.path();
        settingIni->setValue("Path/SubTitleChoose", m_strSubTitlePath);
        emit subTitlePathChanged(m_strSubTitlePath);
    }
    delete settingIni;
}

// 字幕文本
QString MYPlayer::subTitleText() const
{
    return m_strSubTitleText;
}

void MYPlayer::setSubTitleText(QString text)
{
    if(m_strSubTitleText != text) {
        m_strSubTitleText = text;
        emit subTitleTextChanged(m_strSubTitleText);
    }
}

// 视频时长
QString MYPlayer::endTime() const
{
    return m_endTime;
}

void MYPlayer::setEndTime(QString value)
{
    if(m_endTime != value) {
        m_endTime = value;
        emit endTimeChanged(m_endTime);
    }
}

// 当前播放位置（时间）
QString MYPlayer::currentTime() const
{
    return m_currentTime;
}

void MYPlayer::setCurrentTime(QString value)
{
    if(m_currentTime != value) {
        m_currentTime = value;
        emit currentTimeChanged(m_currentTime);
    }
}

